<template>
  <!--<div id = "container" @dblclick="ss_clickListener"></div>-->
  <div id = "container" @dblclick="showAllSensor"></div>

</template>

<script>
  import * as THREE from 'three'
  import resize from './resize'
  import * as OrbitControls from 'three-orbitcontrols'
  export default {
    mixins: [resize],
    // name: 'Graph',
    data() {
      return {
        camera: null,
        scene: null,
        renderer: null,
        controls: null,
        container: null,
        graph_width: 400,
        graph_height: 800,
        cameraZ: 200
      }
    },
    mounted() {
      this.$nextTick(() => {
        this.main()
      })
    },
    methods: {
      main: function() {
        this.initEnvironment()
        this.initLight()
        this.initControls()
        this.animate()

        this.coketower()  //焦炭塔模型
        this.sensor()//传感器
      },
      initEnvironment(){
        // 添加一个div元素
        this.container = document.getElementById('container')
        // document.body.appendChild(container)
        this.scene = new THREE.Scene()// 创建一个新场景
        // 添加一个透视相机
        this.camera = new THREE.PerspectiveCamera(30,
          this.graph_width / this.graph_height, 1, 1000)
        this.camera.position.set(0, 40, 200)// 设置相机位置
        this.camera.lookAt(new THREE.Vector3(0, 0, 0))// 让相机指向原点
        // 渲染
        // antialias:true增加抗锯齿效果
        this.renderer = new THREE.WebGLRenderer({ antialias: true })
        this.renderer.setClearColor(new THREE.Color(0xffffff))// 设置窗口背景颜色为黑
        // this.renderer.setSize(window.innerWidth, window.innerHeight)//设置窗口尺寸
        this.renderer.setSize(this.graph_width, this.graph_height)// 设置窗口尺寸

        // 将this.renderer关联到container，这个过程类似于获取canvas元素
        this.container.appendChild(this.renderer.domElement)
      },
      initLight(){
        // 给场景添加光源
        // 自然光
        var ambientLight = new THREE.AmbientLight(0xffffff)
        this.scene.add(ambientLight)
        // 平行光源
        var directionalLight = new THREE.DirectionalLight(0xffffff)
        directionalLight.position.set(0, 1, 0).normalize()
        this.scene.add(directionalLight)
      },
      initControls: function() {
        this.controls = new OrbitControls(this.camera, this.renderer.domElement)
        this.controls.minDistance = this.cameraZ - 30
        this.controls.maxDistance = this.cameraZ + 30
      },
      update: function() {
        this.controls.update()
      },
      animate: function() {
        requestAnimationFrame(this.animate)
        this.renderer.render(this.scene, this.camera)
        this.update()
      },
      coketower:function(){// 焦炭塔三维模型
        this.coketowercap()    //盖子
        this.coketowerbody() //主体
        this.coketowerbottom()//底部
      },
      sensor:function(){  //传感器三维模型
        this.TemperatureSensor()  //温度传感器
        this.SlopeSensor()    //倾斜传感器
        this.StrainSensor()//高温应变
        this.AcousticSensor()//声发射传感器
        this.VibrationSensor()//振动传感器
      },
      coketowercap:function(){//焦炭塔盖子部分模型
        var a = 20
        var b = 12
        var points = []
        for (var i = 0; i <= a; i = i + 0.5) {
          points.push(new THREE.Vector2(i, Math.sqrt(b * b - (b * b) / (a * a) * i * i)))// 椭圆方程
        }
        var capGeometry = new THREE.LatheGeometry(points, 40)
        var capMaterial = new THREE.MeshBasicMaterial({
          color: 0x304156,
          wireframe: true,
          opacity: 0.4,
          transparent: true
        })
        var cap = new THREE.Mesh(capGeometry, capMaterial)
        cap.position.set(0, 30, 0)
        this.scene.add(cap)

        //* **********************************cap's decoration
        // four Cylinders
        var CyGeo1 = new THREE.CylinderGeometry(3, 3, 5, 30)
        var CyGeo2 = new THREE.CylinderGeometry(0.5, 0.5, 2.2, 15)
        var CyGeo3 = new THREE.CylinderGeometry(0.5, 0.5, 3.5, 15)
        var CyGeo4 = new THREE.CylinderGeometry(0.5, 0.5, 3.5, 15)

        var Cy1 = new THREE.Mesh(CyGeo1, capMaterial) // 中间最大的
        var Cy2 = new THREE.Mesh(CyGeo2, capMaterial) // 左边一个
        var Cy3 = new THREE.Mesh(CyGeo3, capMaterial) // 左边两个
        var Cy4 = new THREE.Mesh(CyGeo4, capMaterial) // 右边一个

        Cy1.position.set(0, 44, 0)
        Cy2.position.set(-6, 42.5, 0)
        Cy3.position.set(-10, 41.7, 0)
        Cy4.position.set(8, 42, 0)

        this.scene.add(Cy1)
        this.scene.add(Cy2)
        this.scene.add(Cy3)
        this.scene.add(Cy4)

        // four flat Cylinders
        var flGeo1 = new THREE.CylinderGeometry(4, 4, 1, 15)
        var flGeo2 = new THREE.CylinderGeometry(1.5, 1.5, 0.8, 15)
        var flGeo3 = new THREE.CylinderGeometry(1.5, 1.5, 0.8, 15)
        var flGeo4 = new THREE.CylinderGeometry(1.5, 1.5, 0.8, 15)

        var fl1 = new THREE.Mesh(flGeo1, capMaterial)
        var fl2 = new THREE.Mesh(flGeo2, capMaterial)
        var fl3 = new THREE.Mesh(flGeo3, capMaterial)
        var fl4 = new THREE.Mesh(flGeo4, capMaterial)

        fl1.position.set(0, 47, 0)
        fl2.position.set(-6, 44, 0)
        fl3.position.set(-10, 43.85, 0)
        fl4.position.set(8, 44.15, 0)

        this.scene.add(fl1)
        this.scene.add(fl2)
        this.scene.add(fl3)
        this.scene.add(fl4)

        // the last small 椭圆
        var points2 = []
        var a2 = 3
        var b2 = 1.5
        for (var ii = 0; ii < 3; ii = ii + 0.2) {
          points2.push(new THREE.Vector2(ii, Math.sqrt(b2 * b2 - (b2 * b2) / (a2 * a2) * ii * ii)))// 椭圆方程
        }
        var smallCGeo = new THREE.LatheGeometry(points2, 15)
        var smallC = new THREE.Mesh(smallCGeo, capMaterial)
        smallC.position.set(0, 47, 0)

        this.scene.add(smallC)
      },
      coketowerbody:function(){//焦炭塔主体部分模型
        var cylinderGeo = new THREE.CylinderGeometry(20, 20, 60, 40, 40)//圆柱体
        var cylinderMat = new THREE.MeshLambertMaterial({// 创建材料
          color: 0x304156,
          wireframe: true,
          opacity: 0.4,
          transparent: true
        })
        var cylinderMesh = new THREE.Mesh(cylinderGeo, cylinderMat)
        cylinderMesh.position.set(0, 0, 0)// 设置圆柱坐标
        this.scene.add(cylinderMesh)// 向场景添加圆柱体
      },

      coketowerbottom:function(){//焦炭塔底部部分模型
        var cylinderGeo1 = new THREE.CylinderGeometry(20, 4, 15, 40, 40)
        var cylinderMat1 = new THREE.MeshLambertMaterial({// 创建材料
          color: 0x304156,
          wireframe: true
        })
        var cylinderGeo2 = new THREE.CylinderGeometry(4, 4, 3, 40, 40)
        var cylinderMat2 = new THREE.MeshLambertMaterial({// 创建材料
          color: 0x304156,
          wireframe: true
        })
        var cylinderGeo3 = new THREE.CylinderGeometry(6, 6, 1, 40, 40)
        var cylinderMat3 = new THREE.MeshLambertMaterial({// 创建材料
          color: 0x304156,
          wireframe: true
        })
        var cylinderMesh1 = new THREE.Mesh(cylinderGeo1, cylinderMat1)
        var cylinderMesh2 = new THREE.Mesh(cylinderGeo2, cylinderMat2)
        var cylinderMesh3 = new THREE.Mesh(cylinderGeo3, cylinderMat3)
        cylinderMesh1.position.set(0, -37.5, 0)// 设置圆柱坐标
        cylinderMesh2.position.set(0, -46.5, 0)// 设置圆柱坐标
        cylinderMesh3.position.set(0, -48.5, 0)// 设置圆柱坐标
        this.scene.add(cylinderMesh1)// 向场景添加圆柱体
        this.scene.add(cylinderMesh2)// 向场景添加圆柱体
        this.scene.add(cylinderMesh3)// 向场景添加圆柱体
      },

      AcousticSensor:function(){//声发射传感器
        var cubeGeo = new THREE.CubeGeometry(2, 1, 1, 5, 5, 5)// 创建立方体
        var cubeMat = new THREE.MeshLambertMaterial({// 创建材料
          color: 0x66ccff,
          wireframe: false
        })
        var cubeMesh1 = new THREE.Mesh(cubeGeo, cubeMat)// 创建立方体网格模型
        var cubeMesh2 = new THREE.Mesh(cubeGeo, cubeMat)// 创建立方体网格模型
        var cubeMesh3 = new THREE.Mesh(cubeGeo, cubeMat)// 创建立方体网格模型
        var cubeMesh4 = new THREE.Mesh(cubeGeo, cubeMat)// 创建立方体网格模型
        var cubeMesh5 = new THREE.Mesh(cubeGeo, cubeMat)// 创建立方体网格模型
        var cubeMesh6 = new THREE.Mesh(cubeGeo, cubeMat)// 创建立方体网格模型
        var cubeMesh7 = new THREE.Mesh(cubeGeo, cubeMat)// 创建立方体网格模型

        cubeMesh1.position.set(0, 0, 0)// 设置立方体的坐标
        cubeMesh2.position.set(20, 0, 0)// 设置立方体的坐标
        cubeMesh3.position.set(-20, 0, 0)// 设置立方体的坐标
        cubeMesh4.position.set(16, 15, 0)// 设置立方体的坐标
        cubeMesh5.position.set(-16, 15, 0)// 设置立方体的坐标
        cubeMesh6.position.set(16, -15, 0)// 设置立方体的坐标
        cubeMesh7.position.set(-16, -15, 0)// 设置立方体的坐标

        this.scene.add(cubeMesh1)// 将立方体添加到场景中
        this.scene.add(cubeMesh2)// 将立方体添加到场景中
        this.scene.add(cubeMesh3)// 将立方体添加到场景中
        this.scene.add(cubeMesh4)// 将立方体添加到场景中
        this.scene.add(cubeMesh5)// 将立方体添加到场景中
        this.scene.add(cubeMesh6)// 将立方体添加到场景中
        this.scene.add(cubeMesh7)// 将立方体添加到场景中
      },

      VibrationSensor:function(){//振动传感器
        var cubeGeo = new THREE.CubeGeometry(1, 1, 1, 5, 5, 5)// 创建立方体
        var cubeMat = new THREE.MeshLambertMaterial({// 创建材料
          color: 0x66ccff,
          wireframe: false
        })
        var cubeMesh1 = new THREE.Mesh(cubeGeo, cubeMat)// 创建立方体网格模型
        var cubeMesh2 = new THREE.Mesh(cubeGeo, cubeMat)// 创建立方体网格模型
        var cubeMesh3 = new THREE.Mesh(cubeGeo, cubeMat)// 创建立方体网格模型
        var cubeMesh4 = new THREE.Mesh(cubeGeo, cubeMat)// 创建立方体网格模型

        cubeMesh1.position.set(21, -28, 0)// 设置立方体的坐标
        cubeMesh2.position.set(21, -16, 0)// 设置立方体的坐标
        cubeMesh3.position.set(21, 3, 0)// 设置立方体的坐标
        cubeMesh4.position.set(21, 28, 0)// 设置立方体的坐标

        cubeMesh1.rotateZ(Math.PI / 4)
        cubeMesh2.rotateZ(Math.PI / 4)
        cubeMesh3.rotateZ(Math.PI / 4)
        cubeMesh4.rotateZ(Math.PI / 4)

        this.scene.add(cubeMesh1)// 将立方体添加到场景中
        this.scene.add(cubeMesh2)// 将立方体添加到场景中
        this.scene.add(cubeMesh3)// 将立方体添加到场景中
        this.scene.add(cubeMesh4)// 将立方体添加到场景中
      },
      StrainSensor:function(){//高温应变传感器
        var sphereGeo = new THREE.SphereGeometry(1, 40, 40)// 创建球体
        var sphereMat = new THREE.MeshLambertMaterial({// 创建材料
          color: 0x65d56a,
          wireframe: false
        })
        var sphereMesh1 = new THREE.Mesh(sphereGeo, sphereMat)// 创建球体网格模型
        var sphereMesh2 = new THREE.Mesh(sphereGeo, sphereMat)// 创建球体网格模型
        var sphereMesh3 = new THREE.Mesh(sphereGeo, sphereMat)// 创建球体网格模型
        var sphereMesh4 = new THREE.Mesh(sphereGeo, sphereMat)// 创建球体网格模型
        var sphereMesh5 = new THREE.Mesh(sphereGeo, sphereMat)// 创建球体网格模型
        var sphereMesh6 = new THREE.Mesh(sphereGeo, sphereMat)// 创建球体网格模型
        var sphereMesh7 = new THREE.Mesh(sphereGeo, sphereMat)// 创建球体网格模型
        var sphereMesh8 = new THREE.Mesh(sphereGeo, sphereMat)// 创建球体网格模型
        sphereMesh1.position.set(0, -27, 0)// 设置球的坐标
        sphereMesh2.position.set(0, -24, 0)// 设置球的坐标
        sphereMesh3.position.set(0, -9, 0)// 设置球的坐标
        sphereMesh4.position.set(0, 18, 0)// 设置球的坐标
        sphereMesh5.position.set(0, 28.5, 0)// 设置球的坐标
        sphereMesh6.position.set(19, -24, 0)// 设置球的坐标
        sphereMesh7.position.set(19, -9, 0)// 设置球的坐标
        sphereMesh8.position.set(-19, 6, 0)// 设置球的坐标
        this.scene.add(sphereMesh1)// 将球体添加到场景
        this.scene.add(sphereMesh2)// 将球体添加到场景
        this.scene.add(sphereMesh3)// 将球体添加到场景
        this.scene.add(sphereMesh4)// 将球体添加到场景
        this.scene.add(sphereMesh5)// 将球体添加到场景
        this.scene.add(sphereMesh6)// 将球体添加到场景
        this.scene.add(sphereMesh7)// 将球体添加到场景
        this.scene.add(sphereMesh8)// 将球体添加到场景
      },
      SlopeSensor:function(){//倾斜传感器
        var cylinderGeo = new THREE.CylinderGeometry(0.5, 1, 1, 40, 40)
        var cylinderMat = new THREE.MeshLambertMaterial({// 创建材料
          color: 0xdd6578,
          wireframe: false
        })
        var cylinderMesh1 = new THREE.Mesh(cylinderGeo, cylinderMat)
        var cylinderMesh2 = new THREE.Mesh(cylinderGeo, cylinderMat)
        var cylinderMesh3 = new THREE.Mesh(cylinderGeo, cylinderMat)
        var cylinderMesh4 = new THREE.Mesh(cylinderGeo, cylinderMat)

        cylinderMesh1.position.set(21, -30, 0)// 设置圆柱坐标
        cylinderMesh2.position.set(21, -15, 0)// 设置圆柱坐标
        cylinderMesh3.position.set(21, 5, 0)// 设置圆柱坐标
        cylinderMesh4.position.set(21, 30, 0)// 设置圆柱坐标

        this.scene.add(cylinderMesh1)// 向场景添加圆柱体
        this.scene.add(cylinderMesh2)// 向场景添加圆柱体
        this.scene.add(cylinderMesh3)// 向场景添加圆柱体
        this.scene.add(cylinderMesh4)// 向场景添加圆柱体
      },

      TemperatureSensor:function(){//温度传感器
        var tetrahedronGeo = new THREE.TetrahedronGeometry(1)
        var tetrahedronMat = new THREE.MeshLambertMaterial({// 创建材料
          color: 0xccd24d,
          wireframe: false
        })
        // 创建四面体网格模型
        var tetrahedronMesh1 = new THREE.Mesh(tetrahedronGeo, tetrahedronMat)
        var tetrahedronMesh2 = new THREE.Mesh(tetrahedronGeo, tetrahedronMat)
        var tetrahedronMesh3 = new THREE.Mesh(tetrahedronGeo, tetrahedronMat)
        var tetrahedronMesh4 = new THREE.Mesh(tetrahedronGeo, tetrahedronMat)
        var tetrahedronMesh5 = new THREE.Mesh(tetrahedronGeo, tetrahedronMat)
        tetrahedronMesh1.position.set(3, -24, 0)// 设置圆柱坐标
        tetrahedronMesh2.position.set(3, -9, 0)// 设置圆柱坐标
        tetrahedronMesh3.position.set(3, 18, 0)// 设置圆柱坐标
        tetrahedronMesh4.position.set(3, 28.5, 0)// 设置圆柱坐标
        tetrahedronMesh5.position.set(-17, 3, 0)// 设置圆柱坐标
        this.scene.add(tetrahedronMesh1)// 向场景添加圆柱体
        this.scene.add(tetrahedronMesh2)// 向场景添加圆柱体
        this.scene.add(tetrahedronMesh3)// 向场景添加圆柱体
        this.scene.add(tetrahedronMesh4)// 向场景添加圆柱体
        this.scene.add(tetrahedronMesh5)// 向场景添加圆柱体
      },
      render: function() {
        this.renderer.render(this.scene, this.camera)
      },
      //监听单击物体
      ss_clickListener: function(event) {
        // 获取 raycaster 和所有模型相交的数组，其中的元素按照距离排序，越近的越靠前
        var intersects = this.getIntersects(event);
        var ss_cMatSelected = new THREE.MeshLambertMaterial({//创建材料
          color: 0x66ccff,
          wireframe: false
        });

        // 获取选中最近的 Mesh 对象
        if (intersects.length != 0 && intersects[0].object instanceof THREE.Mesh) {
          var selectObject = intersects[0].object;
          // console.log(selectObject);
          // console.log(original_mat);
          // console.log(ss_cMat1);
          //changeMaterial(selectObject);
          if (!selectObject.hasChecked) {
            selectObject.material = ss_cMatSelected;
            selectObject.hasChecked = true;
            // console.log(selectObject.material);
            console.log("color changed");
          } else {
            selectObject.material = ss_cMat1;
            selectObject.hasChecked = false;
            console.log("color returned");
          }
        }
      }, //end ss_clickListener

      // 获取与射线相交的对象数组 raycaster
      getIntersects: function(event) {
        event.preventDefault();
        console.log("event.clientX:"+event.offsetX)
        console.log("event.clientY:"+event.offsetY)

        // 声明 raycaster 和 mouse 变量
        var raycaster = new THREE.Raycaster();
        var mouse = new THREE.Vector2();

        // 通过鼠标点击位置,计算出 raycaster 所需点的位置,以屏幕为中心点,范围 -1 到 1
        mouse.x = (event.offsetX / this.graph_width) * 2 - 1;
        mouse.y = -(event.offsetY / this.graph_height) * 2 + 1;

        //通过鼠标点击的位置(二维坐标)和当前相机的矩阵计算出射线位置
        raycaster.setFromCamera(mouse, this.camera);

        // 获取与射线相交的对象数组，其中的元素按照距离排序，越近的越靠前
        var intersects = raycaster.intersectObjects(this.scene.children);

        //返回选中的对象
        return intersects;
      }, //end getIntersects

      //清除所有内容
      clearAll: function () {
        // console.log(this.scene)
        var length = this.scene.children.length
        // console.log(length)
        for(var i = 0; i < length; i++){
          this.scene.remove(this.scene.children[0])
        }
      }, //end clearAll

      //显示方式
      showTowerOnly: function(){
        this.clearAll()
        this.coketower()
        this.initLight()
      },
      showTemperatureOnly: function () {
        this.showTowerOnly()
        this.TemperatureSensor()
      },
      showSlopeOnly: function () {
        this.showTowerOnly()
        this.SlopeSensor()
      },
      showAcousticOnly: function () {
        this.showTowerOnly()
        this.AcousticSensor()
      },
      showVibrationOnly: function () {
        this.showTowerOnly()
        this.VibrationSensor()
      },
      showStrainOnly: function () {
        this.showTowerOnly()
        this.StrainSensor()
      },
      showAllSensor(){
        this.showTowerOnly()
        this.sensor()
        this.$emit('showAll') //向父组件发送请求
      },//end显示方式

      //选择显示方式
      selectedSensor: function(flag){
        switch (flag) {
          case 1:
            this.showAcousticOnly();
            break;
          case 2:
            this.showSlopeOnly();
            break;
          case 3:
            this.showTemperatureOnly();
            break;
          case 4:
            this.showStrainOnly();
            break;
          case 5:
            this.showVibrationOnly();
            break;
          default:
            console.log("The parameter has some problem. Over the range of 1 to 5")
        }
        console.log("sensorChanged")
      }
    }
  }
</script>

<style scoped>

</style>

